home *** CD-ROM | disk | FTP | other *** search
/ 9-Digit Zip Code Directory / 9-Digit Zip Code Directory (American Business Information) (ABIZIP-12).ISO / z4src.zip / Z4CSCP.C < prev    next >
C/C++ Source or Header  |  1995-08-17  |  17KB  |  509 lines

  1. //----------------------------------------------------------------------------
  2. //                            MODULE DESCRIPTION
  3. //
  4. //  Module:    z4cscp.c
  5. //   Title:    ZIP+4 Engine
  6. //  Notice:    John M. Weeder
  7. //                 Copyright (c) 1993. All rights reserved.
  8. //             This module contains proprietary information and should be 
  9. //                treated as confidential.
  10. //
  11. //----------------------------------------------------------------------------
  12. //                           MAINTENANCE HISTORY
  13. //
  14. // $Workfile$
  15. // $Revision$
  16. //   $Author$
  17. //     $Date$
  18. //      $Log$    
  19. //
  20. //----------------------------------------------------------------------------
  21. //                             MODULE NARRATIVE
  22. //
  23. //
  24. //    This module contains the compressor for the city/state file.
  25. //
  26. //    The code in this module should be written entirely in C. 
  27. //    Do not use any C++ constructs.
  28. //
  29. //    This module is portable to:
  30. //        DOS 3.X+
  31. //        MS Windows 3.X+
  32. //        OS/2 2.X+
  33. //        OS/2 2.0 PM
  34. //        SCO UNIX.
  35. //
  36. //    The following compilers are supported:
  37. //        MSC 6.0A
  38. //        MSC/C++ 7.0
  39. //        Borland C++ 3.1 for DOS
  40. //        Borland C++ 1.0 for OS/2 2.X
  41. //        SCO UNIX cc
  42. //
  43. //----------------------------------------------------------------------------
  44. #include <z4.h>
  45.  
  46.  
  47. //----------------------------------------------------------------------------
  48. //    Globals
  49. //----------------------------------------------------------------------------
  50. typedef struct _G
  51. {
  52.    PVOID pcache;                        // Word/string cache
  53.    BOOL fError;                         // Error while compressing?
  54.    Z4_CS ctystPrev;                     // Previous city/state record
  55.    Z4_CS ctystCur;                      // Current city/state record
  56.    Z4_CS ctyst;                         // City/state being processed
  57.    BOOL fPending;                       // Record pending?
  58.    SIZET cZip;
  59.    SIZET cRecType;
  60.    SIZET cPof;
  61.    SIZET cLL;
  62.    SIZET cState;
  63.    SIZET cCity;
  64.    SIZET cCityAbbrev;
  65.    SIZET cLLName;
  66.    SIZET cCountyNo;
  67.    SIZET cCountyName;
  68.    SIZET cFacility;
  69.    PZ4_PF_TBL ppf_tbl;
  70. } G;
  71. static G g;
  72.  
  73.  
  74. //----------------------------------------------------------------------------
  75. //    Prototypes
  76. //----------------------------------------------------------------------------
  77. static BOOL FN_L Z4CSCompressAppend(PBYTE, SIZET, PSIZET);
  78. static BOOL FN_L Z4CSCompressEqual(PZ4_CS, PZ4_CS);
  79. static BOOL FN_L Z4CSCompressInitialize(void);
  80. static BOOL FN_L Z4CSCompressReset(void);
  81. static BOOL FN_L Z4CSCompressTerminate(void);
  82. static SHORT FN_L Z4CSCompressValidate(PPSZ);
  83.  
  84.  
  85. //----------------------------------------------------------------------------
  86. //   Description:    Compression function    
  87. //    Parameters:    pdatacomp    Compressor data
  88. //       Returns:    Compression function result code. See data.h.
  89. //----------------------------------------------------------------------------
  90. SHORT FN_E Z4CSCompress(PDATACOMP pdatacomp)
  91. {
  92.     LONG lRec = pdatacomp->dlmrec.lId;
  93.     PPSZ ppsz = pdatacomp->dlmrec.apsz;
  94.     SHORT sResult;
  95.  
  96.     switch (lRec)
  97.         {
  98.         case DAI_INITIALIZE:                    // Initialize at startup
  99.             {
  100.             PDATACFG pcfg  = pdatacomp->dlmrec.pcfg;
  101.  
  102.             if (!Z4CSCompressInitialize()
  103.             || !Z4PofCreate(&g.ppf_tbl, Z4_PF_TBL_DISCARD_MAX)
  104.             || !Z4PofRead(g.ppf_tbl, Z4_PF_TBL_DISCARD))
  105.                 return DAO_FAILURE;
  106.  
  107.     g.cZip         = DataField(pcfg, "zipcode");
  108.     g.cRecType     = DataField(pcfg, "record_type_code");
  109.     g.cCity        = DataField(pcfg, "city_name");
  110.     g.cCityAbbrev  = DataField(pcfg, "city_abbrev");
  111.     g.cFacility    = DataField(pcfg, "facility");
  112.     g.cLL          = DataField(pcfg, "last_line");
  113.     g.cLLName      = DataField(pcfg, "last_line_name");
  114.     g.cPof         = DataField(pcfg, "finance");
  115.     g.cState       = DataField(pcfg, "state_abbrev");
  116.     g.cCountyNo    = DataField(pcfg, "county_no");
  117.     g.cCountyName  = DataField(pcfg, "county_name");
  118.             return DAO_SUCCESS;
  119.             }
  120.         case DAI_TERMINATE:                    // Terminate
  121.         case DAI_FAILURE:
  122.             Z4CSCompressTerminate();
  123.             return DAO_SUCCESS;
  124.  
  125.         case DAI_START_BLK:                    // Start block
  126.             Z4CSCompressReset();
  127.             return DAO_SUCCESS;
  128.  
  129.         case DAI_END_BLK:                        // End block
  130.             return DAO_SUCCESS;
  131.  
  132.         case DAI_LAST_REC:                    // Last record pending, append and flush
  133.             if (g.fError)
  134.                 return DAO_FAILURE;
  135.  
  136.             Z4CSCompressAppend(pdatacomp->pb, pdatacomp->cbMax, &pdatacomp->cb);
  137.             return DAO_FLUSH;
  138.         }
  139.     sResult = Z4CSCompressValidate(ppsz);
  140.     if (sResult == (SHORT)g.cState || Z4PofFind(g.ppf_tbl, ppsz[g.cPof]) >= 0L) // Invalid state, or invalid POF -- discard record
  141.         return DAO_SKIP;
  142.  
  143.     if (sResult >= 0)  {
  144.         Output("\n*** Field %d has invalid value in record %ld.\n    '%s'='%s'\n",
  145.             sResult, lRec,
  146.             pdatacomp->dlmrec.pcfg->afld[sResult].szName,
  147.             ppsz[sResult]);
  148.  
  149.     g.fError = TRUE;
  150.     }
  151.     if (g.fError)            // If an error occurred, just keep
  152.         return DAO_SUCCESS;    //  scanning for invalid recods
  153.     printf("%ld",lRec);
  154.     Assert(g.ctyst.state >= g.ctystCur.state);
  155.     if (g.fPending)
  156.         {
  157.         if (g.ctyst.state == g.ctystCur.state
  158.       && strcmp(g.ctyst.szCity, g.ctystCur.szCity) == 0)
  159.             {
  160.             if (!Z4CSCompressEqual(&g.ctyst, &g.ctystCur))
  161.                 {
  162.                 Z4CSCompressAppend(pdatacomp->pb, pdatacomp->cbMax, &pdatacomp->cb);
  163.                 return DAO_MARK_FLUSH;
  164.                 }
  165.             strcpy(g.ctystCur.szZip5Hi, g.ctyst.szZip5Lo);
  166.             return DAO_NEXT;
  167.             }
  168.         else
  169.             {
  170.             Z4CSCompressAppend(pdatacomp->pb, pdatacomp->cbMax, &pdatacomp->cb);
  171.             return DAO_MARK_FLUSH;
  172.             }
  173.         }
  174.     g.ctystCur = g.ctyst;
  175.     g.fPending = TRUE;
  176.     return DAO_NEXT;
  177. }
  178.  
  179.  
  180. //----------------------------------------------------------------------------
  181. //   Description:    Append a compressed record to the output buffer.
  182. //    Parameters:    pctyst        City/state record to append
  183. //                        pb                Buffer for compressed data.
  184. //                        cb                Size of buffer.
  185. //                        pcb            Pointer to variable containing current size of
  186. //                                        compressed data. Updated on return to contain
  187. //                                        size of compressed data after this record is
  188. //                                        processed.
  189. //       Returns:    TRUE if successful.
  190. //----------------------------------------------------------------------------
  191. static BOOL FN_L Z4CSCompressAppend(PBYTE pb, SIZET cb, PSIZET pcb)
  192. {
  193.     BYTE b1 = 0, b2 = 0;
  194.     PBYTE pbStart = pb;
  195.     SIZET cString;
  196.  
  197.     //
  198.     //    Create bit flags indicating which data is being written
  199.     //
  200.     NOTUSED(cb);
  201.     if (strcmp(g.ctystPrev.szZip5Hi, g.ctystCur.szZip5Hi) != 0)
  202.         b1 |= CS1_ZIP5_HI;
  203.     if (strcmp(g.ctystPrev.szZip5Lo, g.ctystCur.szZip5Lo) != 0)
  204.         b1 |= CS1_ZIP5_LO;
  205.     if (strcmp(g.ctystPrev.szCity, g.ctystCur.szCity) != 0)
  206.         b1 |= CS1_CITY;
  207.     if (strcmp(g.ctystPrev.szCityAbbrev, g.ctystCur.szCityAbbrev) != 0)
  208.         b1 |= CS1_CITY_ABBREV;
  209.     if (g.ctystPrev.facility != g.ctystCur.facility)
  210.         b1 |= CS1_FACILITY;
  211.     if (g.ctystPrev.state != g.ctystCur.state)
  212.         b1 |= CS1_STATE;
  213.     if (g.ctystPrev.rectype != g.ctystCur.rectype)
  214.         b1 |= CS2_REC_TYPE;
  215.     if (strcmp(g.ctystPrev.szFinance, g.ctystCur.szFinance) != 0)
  216.         b2 |= CS2_FINANCE;
  217.     if (strcmp(g.ctystPrev.szLastLine, g.ctystCur.szLastLine) != 0)
  218.         b2 |= CS2_LAST_LINE;
  219.     if (strcmp(g.ctystPrev.szLastLineName, g.ctystCur.szLastLineName) != 0)
  220.         b2 |= CS2_LAST_LINE_NAME;
  221.     if (strcmp(g.ctystPrev.szCountyNo, g.ctystCur.szCountyNo) != 0)
  222.         b2 |= CS2_COUNTY_NO;
  223.     if (strcmp(g.ctystPrev.szCounty, g.ctystCur.szCounty) != 0)
  224.         b2 |= CS2_COUNTY;
  225.     //
  226.     // If last line and finance number are changing and the last line
  227.     //    and finance are the same, set a special bit flag.
  228.     //
  229.     if ((b2 & CS2_FINANCE)
  230.     && (b2 & CS2_LAST_LINE)
  231.     && strcmp(g.ctystCur.szFinance, g.ctystCur.szLastLine) == 0)
  232.         {
  233.         b2 &= ~CS2_LAST_LINE;
  234.         b2 |=    CS2_LL_IS_POF;
  235.         }
  236.     //
  237.     // If last line name and city name are changing and they
  238.     //    are the same, set a special bit flag.
  239.     //
  240.     if ((b1 & CS1_CITY)
  241.     && (b2 & CS2_LAST_LINE_NAME)
  242.     && strcmp(g.ctystCur.szCity, g.ctystCur.szLastLineName) == 0)
  243.         {
  244.         b2 &= ~CS2_LAST_LINE_NAME;
  245.         b2 |=    CS2_LL_IS_CITY;
  246.         }
  247.     //
  248.     // If ZIP 5 hi range is changing to blank, set bit flag.
  249.     //
  250.     if ((b1 & CS1_ZIP5_HI)
  251.     && !g.ctystCur.szZip5Hi[0])
  252.         {
  253.         b1 &= ~CS1_ZIP5_HI;
  254.         b2 |=    CS1_NO_ZIP5_HI;
  255.         }
  256.     if (b2)
  257.         b1 |= CS_BYTE_FOLLOWS;
  258.     //
  259.     //    Write compressed data
  260.     //
  261.     Assert(b1);
  262.     *pb++ = b1;                                    // Write bit flags
  263.     if (b2)
  264.         *pb++ = b2;
  265.     if (b1 & CS1_ZIP5_HI)
  266.         {
  267.         stra2b(pb, MAX_ZIP5_BCD, g.ctystCur.szZip5Hi, MAX_ZIP5);
  268.         pb += MAX_ZIP5_BCD;
  269.         }
  270.     if (b1 & CS1_ZIP5_LO)
  271.         {
  272.         stra2b(pb, MAX_ZIP5_BCD, g.ctystCur.szZip5Lo, MAX_ZIP5);
  273.         pb += MAX_ZIP5_BCD;
  274.         }
  275.     if (b1 & CS1_CITY)
  276.         {
  277.         StringEncode(g.pcache, pb, &cString, g.ctystCur.szCity);
  278.         pb += cString;
  279.         }
  280.     if (b1 & CS1_CITY_ABBREV)
  281.         {
  282.         StringEncode(g.pcache, pb, &cString, g.ctystCur.szCityAbbrev);
  283.         pb += cString;
  284.         }
  285.     if (b1 & CS1_STATE)
  286.         *pb++ = (BYTE)g.ctystCur.state;
  287.     if (b1 & CS1_FACILITY)
  288.         *pb++ = (BYTE)g.ctystCur.facility;
  289.     if (b1 & CS2_REC_TYPE)
  290.         *pb++ = (BYTE)g.ctystCur.rectype;
  291.     if (b2 & CS2_FINANCE)
  292.         {
  293.         stra2b(pb, MAX_FINANCE_BCD, g.ctystCur.szFinance, MAX_FINANCE);
  294.         pb += MAX_FINANCE_BCD;
  295.         }
  296.     if (b2 & CS2_LAST_LINE)
  297.         {
  298.         stra2b(pb, MAX_LAST_LINE_BCD, g.ctystCur.szLastLine, MAX_LAST_LINE);
  299.         pb += MAX_LAST_LINE_BCD;
  300.         }
  301.     if (b2 & CS2_LAST_LINE_NAME)
  302.         {
  303.         StringEncode(g.pcache, pb, &cString, g.ctystCur.szLastLineName);
  304.         pb += cString;
  305.         }
  306.     if (b2 & CS2_COUNTY_NO)
  307.         {
  308.         stra2b(pb, MAX_COUNTY_NO_BCD, g.ctystCur.szCountyNo, MAX_COUNTY_NO);
  309.         pb += MAX_COUNTY_NO_BCD;
  310.         }
  311.     if (b2 & CS2_COUNTY)
  312.         {
  313.         StringEncode(g.pcache, pb, &cString, g.ctystCur.szCounty);
  314.         pb += cString;
  315.         }
  316.     //
  317.     //    Clean up
  318.     //
  319.     *pcb = (SIZET)(pb - pbStart);            // Return number of bytes written
  320.     g.ctystPrev = g.ctystCur;                // Store record which was written and
  321.     g.fPending = FALSE;                        //  update flags
  322.     return TRUE;
  323. }
  324.  
  325.  
  326. //----------------------------------------------------------------------------
  327. //   Description:    Compare two city/state records except for ZIP range
  328. //    Parameters:    pctyst1        Records to compare
  329. //                        pctyst2
  330. //       Returns:    TRUE if equal.
  331. //----------------------------------------------------------------------------
  332. static BOOL FN_L Z4CSCompressEqual(PZ4_CS pctyst1, PZ4_CS pctyst2)
  333. {
  334.     return pctyst1->facility == pctyst2->facility
  335.     && pctyst1->rectype  == pctyst2->rectype
  336.     && pctyst1->state  == pctyst2->state
  337.     && strcmp(pctyst1->szCity,pctyst2->szCity) == 0
  338.     && strcmp(pctyst1->szCityAbbrev,pctyst2->szCityAbbrev) == 0
  339.     && strcmp(pctyst1->szFinance,pctyst2->szFinance) == 0
  340.     && strcmp(pctyst1->szLastLine,pctyst2->szLastLine) == 0
  341.     && strcmp(pctyst1->szLastLineName,pctyst2->szLastLineName) == 0
  342.     && strcmp(pctyst1->szCountyNo,pctyst2->szCountyNo) == 0
  343.     && strcmp(pctyst1->szCounty,pctyst2->szCounty) == 0;
  344. }
  345.  
  346.  
  347. //----------------------------------------------------------------------------
  348. //   Description:    Initialize city/state record compressor
  349. //    Parameters:
  350. //       Returns:    TRUE if successful.
  351. //----------------------------------------------------------------------------
  352. static BOOL FN_L Z4CSCompressInitialize(void)
  353. {
  354.     memset(&g, 0, sizeof(g));
  355.     g.pcache = StringCreate(Z4_CS_WORD_CACHE, CP_WORD_VERIFY);
  356.     if (g.pcache == NULL)
  357.         return FALSE;
  358.     return Z4CSCompressReset();
  359. }
  360.  
  361.  
  362. //----------------------------------------------------------------------------
  363. //   Description:    Reset record compressor to compress another block
  364. //    Parameters:
  365. //       Returns:    TRUE if successful.
  366. //----------------------------------------------------------------------------
  367. static BOOL FN_L Z4CSCompressReset(void)
  368. {
  369.     StringReset(g.pcache);                    // Reset string cache
  370.                                                     // Clear pending records
  371.     memset(&g.ctyst, 0, sizeof(g.ctyst));
  372.     memset(&g.ctystPrev, 0, sizeof(g.ctystPrev));        // Set default record characteristics
  373.     g.ctystPrev.facility = Z4_FACILITY_PO;
  374.     g.ctystPrev.rectype = Z4_CS_TYPE_NON_UNIQUE;
  375.     g.ctystPrev.state = Z4_ST_FIRST;
  376.  
  377.     g.fPending = FALSE;                        // Reset flags
  378.     return TRUE;
  379. }
  380.  
  381.  
  382. //----------------------------------------------------------------------------
  383. //   Description:    Terminate record compressor
  384. //    Parameters:
  385. //       Returns:    TRUE if successful.
  386. //----------------------------------------------------------------------------
  387. static BOOL FN_L Z4CSCompressTerminate(void)
  388. {
  389.     if (g.pcache)                                // Close word cache
  390.         StringDestroy(g.pcache);
  391.     Z4PofDestroy(g.ppf_tbl);
  392.     memset(&g, 0, sizeof(g));
  393.     return TRUE;
  394. }
  395.  
  396.  
  397. //----------------------------------------------------------------------------
  398. //   Description:   Check if all characters in a string are numeric or if
  399. //                  the second character is an A.
  400. //    Parameters:    pcsz        String
  401. //       Returns:    TRUE if all characters are numeric
  402. //----------------------------------------------------------------------------
  403. BOOL FN_E strisnumeric2(PCSZ pcsz)
  404. {
  405.     return strisvalid(pcsz, "[aAbBcC0-9]*");
  406. }
  407.  
  408. //----------------------------------------------------------------------------
  409. //   Description:    Validate city/state data and copy to fields.
  410. //    Parameters:    ppsz            Record data
  411. //       Returns:    -1 if successful. Field id of invalid field
  412. //----------------------------------------------------------------------------
  413. static SHORT FN_L Z4CSCompressValidate(PPSZ ppsz)
  414. {
  415.  
  416.     memset(&g.ctyst, 0, sizeof(g.ctyst));
  417.         // Check valid zip code
  418.     if (!strisnumeric(ppsz[g.cZip])    || strlen(ppsz[g.cZip]) != MAX_ZIP5)
  419.         return (SHORT)g.cZip;
  420.     strcpy(g.ctyst.szZip5Lo, ppsz[g.cZip]);
  421.     g.ctyst.rectype = Z4FindCSRecordType(ppsz[g.cRecType]); // Check record type
  422.     if (g.ctyst.rectype == Z4_CS_TYPE_INVALID)
  423.         return (SHORT)g.cRecType;
  424.     if (!strisnumeric(ppsz[g.cPof])        // Finance number
  425.     || strlen(ppsz[g.cPof]) != MAX_FINANCE)
  426.         return (SHORT)g.cPof;
  427.     strcpy(g.ctyst.szFinance, ppsz[g.cPof]);
  428.  
  429.     //  Last line number may start with the letters B,C,N,V,W,X,Y,Z
  430.     //  or a digit.  It must be 6 characters in length.
  431.     //  The characters N thru Z are converted to A thru F so that it can
  432.     //  be encoded in bcd.
  433.  
  434.  
  435.     // an error is in the data file for Texarkana Ar.  W2ZZZZ is an invalid
  436.     // Last Line entry, so am converting it to W2AAAA.
  437.  
  438.     if (ppsz[g.cLL][2]) {
  439.       if (!(isdigit(ppsz[g.cLL][2]) && (ppsz[g.cLL][2]) == 'Z')
  440.          || !isdigit(ppsz[g.cLL][3] && (ppsz[g.cLL][3]) == 'Z')
  441.          || !isdigit(ppsz[g.cLL][4] && (ppsz[g.cLL][4]) == 'Z')
  442.          || !isdigit(ppsz[g.cLL][5] && (ppsz[g.cLL][5]) == 'Z')) {
  443.          ppsz[g.cLL][2] = 'A';
  444.          ppsz[g.cLL][3] = 'A';
  445.          ppsz[g.cLL][4] = 'A';
  446.          ppsz[g.cLL][5] = 'A';
  447.       }
  448.     }
  449.  
  450.     if (ppsz[g.cLL][0])        // If a last line number is present
  451.         {            //  copy it
  452.         if (!(isdigit(ppsz[g.cLL][0])
  453.         || ppsz[g.cLL][0] == 'B'
  454.         || ppsz[g.cLL][0] == 'C'
  455.         || ppsz[g.cLL][0] == 'N'
  456.         || ppsz[g.cLL][0] == 'V'
  457.         || ppsz[g.cLL][0] == 'W'
  458.         || ppsz[g.cLL][0] == 'X'
  459.         || ppsz[g.cLL][0] == 'Y'
  460.         || ppsz[g.cLL][0] == 'Z')
  461.         || !strisnumeric2(ppsz[g.cLL] + 1)
  462.         // use the above test to see if we can get A to work
  463. //        || !strisnumeric(ppsz[g.cLL] + 1) //original code
  464.         || strlen(ppsz[g.cLL]) != MAX_LAST_LINE)
  465.             return (SHORT)g.cLL;  // invalid last line
  466.  
  467.         strcpy(g.ctyst.szLastLine, ppsz[g.cLL]);
  468.         if (g.ctyst.szLastLine[0] == 'N')
  469.             g.ctyst.szLastLine[0] = 'A';
  470.         if (g.ctyst.szLastLine[0] == 'V')
  471.             g.ctyst.szLastLine[0] = 'B';
  472.         if (g.ctyst.szLastLine[0] == 'W')
  473.             g.ctyst.szLastLine[0] = 'C';
  474.         if (g.ctyst.szLastLine[0] == 'X')
  475.             g.ctyst.szLastLine[0] = 'D';
  476.         if (g.ctyst.szLastLine[0] == 'Y')
  477.             g.ctyst.szLastLine[0] = 'E';
  478.         if (g.ctyst.szLastLine[0] == 'Z')
  479.             g.ctyst.szLastLine[0] = 'F';
  480.         }
  481.     else                                            // Else, use finance number
  482.         strcpy(g.ctyst.szLastLine, g.ctyst.szFinance);
  483.                                                     // Check state code
  484.     g.ctyst.state = Z4FindState(ppsz[g.cState]);
  485.     if (g.ctyst.state == Z4_ST_INVALID)    // Invalid state code
  486.         return (SHORT)g.cState;
  487.     strcpy(g.ctyst.szCity, Z4Clean(ppsz[g.cCity]));
  488.     strcpy(g.ctyst.szCityAbbrev, Z4Clean(ppsz[g.cCityAbbrev]));
  489.     strcpy(g.ctyst.szLastLineName, Z4Clean(ppsz[g.cLLName]));
  490.     if (ppsz[g.cCountyNo][0])
  491.         {                                            // Check county number
  492.         if (!strisnumeric(ppsz[g.cCountyNo])
  493.         || strlen(ppsz[g.cCountyNo]) != MAX_COUNTY_NO)
  494.            return (SHORT)g.cCountyNo;
  495.        strcpy(g.ctyst.szCountyNo, ppsz[g.cCountyNo]);
  496.        strcpy(g.ctyst.szCounty, ppsz[g.cCountyName]);
  497.         }
  498.     else
  499.        strcpy(g.ctyst.szCountyNo, "000");
  500.                                                     // Facility code
  501.     g.ctyst.facility =  Z4FindFacility(ppsz[g.cFacility]);
  502.     if (g.ctyst.facility == Z4_FACILITY_INVALID)
  503.             return (SHORT)g.cFacility;
  504.     return -1;
  505. }
  506. //----------------------------------------------------------------------------
  507. //------------------------------- End of File --------------------------------
  508. //----------------------------------------------------------------------------
  509.